package com.senyint.imsdk;

import java.io.UnsupportedEncodingException;

import org.jivesoftware.smack.Conversation;
import org.jivesoftware.smack.ConversationMessageListener;
import org.jivesoftware.smack.packet.Message;
import org.jivesoftware.smack.packet.Packet;
import org.jivesoftware.smackx.ChatState;
import org.jivesoftware.smackx.packet.ChatStateExtension;
import com.senyint.imsdk.listener.SdkHandlerListener;
import com.senyint.imsdk.util.PacketUtil;
import com.senyint.imsdk.util.StringUtil;

/**
 * gloabs context for sdk<br>
 * 	init. when application starts
 * @author hui
 *
 */
public final class SdkContext {
	private static SdkContext me = new SdkContext();
	
	private SmackHelper2 smackHelper = null ;
	private SharedPreferencesHelper prefHelper = null ;
	private SdkHandlerListener mSdkHandlerListener = null ;
	private IServiceListener mCallbackWhenServiceStartup = null ;
	private boolean setup = false ;
	
	public static SdkContext me(){
		return me ;
	}
	
	private SdkContext(){}
	
	public void init(){
		if(setup) return ;
		prefHelper = new SharedPreferencesHelper("sdk_ctx");
		setup = true ;
	}

	public SmackHelper2 help() {
		return smackHelper;
	}

	public void setSmackHelper(SmackHelper2 smackHelper) {
		this.smackHelper = smackHelper;
	}
	

	public void remove(String key){
		prefHelper.removeAttribute(key);
	}
	
	public void set(String key,Object val){
		if(val == null) return ;
		else if(val instanceof Boolean)
			prefHelper.setAttribute(key, (Boolean)val);
		else if(val instanceof Integer)
			prefHelper.setAttribute(key, (Integer)val);
		else if(val instanceof Long)
			prefHelper.setAttribute(key, (Long)val);
		else 
			prefHelper.setAttribute(key,val.toString());
	}
	
	@SuppressWarnings("unchecked")
	public <T> T get(String key,T val){
		if(val instanceof Boolean)
			return (T) Boolean.valueOf(prefHelper.getAttribute(key));
		else if(val instanceof Integer)
			return (T) prefHelper.getAttribute(key, (Integer)val);
		else if(val instanceof Long)
			return (T) prefHelper.getAttribute(key, (Long)val);
		
		return (T) (prefHelper.getString(key)==null?val:prefHelper.getString(key));
		
	}
	
	public String getServiceName() {
		return prefHelper.getString(ISdkConfig.XMPP_SERVICE_NAME, null) ;
	}

	public String getHost() {
		return prefHelper.getString(ISdkConfig.XMPP_HOST,ISdkConfig.DEFAULT_HOST) ;
	}

	public void setHost(String host) {
		prefHelper.setAttribute(ISdkConfig.XMPP_HOST,host) ;
	}

	
	public String getResourceName() {
		return prefHelper.getString(ISdkConfig.XMPP_RESOURCE_NAME,ISdkConfig.DEFAULT_RESOURCE_NAME) ;
	}
	
	public String getUserName() {
		return prefHelper.getString(ISdkConfig.XMPP_USER_NAME,"") ;
	}
	
	public String getPassword() {
		String pwd = prefHelper.getString(ISdkConfig.XMPP_PASSWORD,"");
		if(!StringUtil.isEmpty(pwd)){
			try {
				return new String(StringUtil.hexStringToByte(pwd),ISdkConfig.DEFAULT_ENCODNG);
			} catch (UnsupportedEncodingException e) {
			}
		}
		return null ;
	}
	
	public void setPassword(String password) {
		try {
			set(ISdkConfig.XMPP_PASSWORD, StringUtil.bytesToHexString(password.getBytes(ISdkConfig.DEFAULT_ENCODNG)));
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
	}
	
	protected void setPort(int port){
		set(ISdkConfig.XMPP_PORT, port);
	}
	
	protected void setServiceName(String service){
		set(ISdkConfig.XMPP_SERVICE_NAME, service);
	}
	
	protected void setResourceName(String res){
		set(ISdkConfig.XMPP_RESOURCE_NAME, res);
	}

	public void setUserName(String login) {
		set(ISdkConfig.XMPP_USER_NAME, login);
	}

	public void removeUserName() {
		remove(ISdkConfig.XMPP_USER_NAME);
	}

	public void removePassword() {
		remove(ISdkConfig.XMPP_PASSWORD);
	}
	
	public void removeUserToken() {
		remove(ISdkConfig.USER_TOKEN);
	}
	
	public void removeResource() {
		remove(ISdkConfig.XMPP_RESOURCE_NAME);
	}

	public void setSdkHandlerListener(SdkHandlerListener mSdkHandlerListener) {
		this.mSdkHandlerListener = mSdkHandlerListener;
	}

	public void setCallbackWhenServiceStartup(IServiceListener callbackWhenServiceStartup) {
		this.mCallbackWhenServiceStartup = callbackWhenServiceStartup;
	}
	
	/***
	 * 服务启动后的回调
	 */
	public void callbackWhenServiceStartup(){
		if(mSdkHandlerListener != null){
			smackHelper.setSdkHandlerListener(mSdkHandlerListener);
		}
		if( mCallbackWhenServiceStartup != null){
			mCallbackWhenServiceStartup.onCreated();
		}
	}

	public Conversation createConversationChat(String participant, String topic, ConversationMessageListener listener){
		if(smackHelper.getConversationManager()!= null){
			return smackHelper.getConversationManager().createConversationChat(participant, topic, listener);
		}
		return null ;
	}
	
	/******************************	functions	**********************************/
	public boolean isAuthenticated() {
		return smackHelper.isAuthenticated();
	}

	public Integer onLogin(String uid, String token) {
		return smackHelper.onLogin(uid, token);
	}

	public void onSend(Packet packet) {
		smackHelper.onSend(packet);
	}
	
	public void onLogout() {
		smackHelper.onLogout();
	}
	
	public void sendChatState(String tojid, ChatState state) throws SendPacketException {
		if (!isSendChatStateNotification()) {
			return;
		}
		tojid = PacketUtil.getBareJID(tojid);
		Message message = new Message(tojid);
		ChatStateExtension extension = new ChatStateExtension(state);
		message.addExtension(extension);

		onSend(message);
	}

	private boolean isSendChatStateNotification() {
		return false;
	}
	
	public static interface IServiceListener{
		public void onCreated();
	}
	
}
